package com.mastercard.auth
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AccountException
import org.apache.shiro.authc.IncorrectCredentialsException
import org.apache.shiro.authc.UnknownAccountException
import org.apache.shiro.authc.SimpleAccount
import org.apache.shiro.authz.permission.WildcardPermission

import com.mastercard.common.constants.CommonConstants;

class ShiroDbRealm {
     static authTokenClass = org.apache.shiro.authc.UsernamePasswordToken

    def credentialMatcher
    def shiroPermissionResolver
    def userService

    def authenticate(authToken) {
		println 'authenticate(authToken)'
        log.info "Attempting to authenticate ${authToken.username} in DB realm..."
        def username = authToken.username

        // Null username is invalid
        if (username == null) {
            throw new AccountException('Null usernames are not allowed by this realm.')
        }

        // Get the user with the given username. If the user is not
        // found, then they don't have an account and we throw an
        // exception.
        def user = User.findByLogin(username)
        log.info "Found user '${user?.login}' in DB"
        if (!user) {
            throw new UnknownAccountException("No account found for user [${username}]")
        }

        // Now check the user's password against the hashed value stored
        // in the database.
        def account = new SimpleAccount(username, user.password, "ShiroDbRealm")
		log.info "user.password = ${user.password}"
		log.info credentialMatcher
        if (!credentialMatcher.doCredentialsMatch(authToken, account)) {
            log.info 'Invalid password (DB realm)'
            throw new IncorrectCredentialsException("Invalid password for user '${username}'")
        }else{
			SecurityUtils.subject.session.setAttribute(CommonConstants.LOGIN_USER, user)
        }

        return account
    }

    def hasRole(principal, roleName) {
        def user = User.findByLogin(principal)

        return null != user?.roles?.find { it.name == roleName }
    }

    def hasAllRoles(principal, roles) {
        def criteria = User.createCriteria()
        def r = criteria.list {
            roles {
                'in'('name', roles)
            }
            eq('login', principal)
        }

        return r.size() == roles.size()
    }

    boolean isPermitted(principal, requiredPermission) {
		log.info "principal = ${principal}, requiredPermission = ${requiredPermission}"
		return true
//        def permissions = userService.permissionsForUser(principal)
//        def retval = permissions?.find { permString ->
//            // Create a real permission instance from the database
//            // permission.
//            def perm = shiroPermissionResolver.resolvePermission(permString)
//
//            // Now check whether this permission implies the required
//            // one.
//            if (perm.implies(requiredPermission)) {
//                // User has the permission!
//                return true
//            }
//            else {
//                return false
//            }
//        }
//
//        return retval != null
    }
}
